from flask import Flask, jsonify, request
import requests
import parsel
import csv

app = Flask(__name__, static_folder='.', static_url_path='')


@app.route('/')
def index():
    return app.send_static_file('index.html')


@app.route('/get_travel_data')
def get_travel_data():
    data = []
    try:
        with open('whereToTravel.csv', mode='r', encoding='utf-8') as f:
            csv_reader = csv.DictReader(f)
            for row in csv_reader:
                data.append(row)
    except FileNotFoundError:
        data = crawl_travel_data()
    return jsonify(data)


@app.route('/get_wordcloud')
def get_wordcloud():
    from wordcloud import WordCloud
    import jieba
    import io
    import base64

    texts = []
    with open('whereToTravel.csv', encoding='utf-8') as f:
        for row in csv.DictReader(f):
            texts.append(row['title'] + " " + row['trip'])

    # 中文分词+过滤
    words = " ".join(jieba.cut("".join(texts)))
    wc = WordCloud(
        font_path='msyh.ttc',
        background_color='white',
        width=800,
        height=600
    ).generate(words)

    img = io.BytesIO()
    wc.to_image().save(img, 'PNG')
    return jsonify({"image": base64.b64encode(img.getvalue()).decode()})

@app.route('/get_data')
def get_data():
    option = request.args.get('option')
    try:
        with open('whereToTravel.csv', mode='r', encoding='utf-8') as f:
            csv_reader = csv.DictReader(f)
            original_data = list(csv_reader)

        if option == 'popularCities':
            # 热门城市分析
            locations = {}
            for item in original_data:
                if item['trip']:
                    for location in item['trip'].split('\u3000'):
                        if location and location not in ['深度游', '穷游', '美食', '古镇', '自驾', '温泉', '徒步',
                                                         '摄影']:
                            locations[location] = locations.get(location, 0) + 1
            sorted_locations = sorted(locations.items(), key=lambda x: x[1], reverse=True)[:10]
            labels = [x[0] for x in sorted_locations]
            values = [x[1] for x in sorted_locations]

        elif option == 'travelMonth':
            # 旅游月份分析
            months = {str(i).zfill(2): 0 for i in range(1, 13)}
            for item in original_data:
                if item['date']:
                    month = item['date'].split('-')[1]
                    months[month] = months.get(month, 0) + 1
            labels = [f"{int(m)}月" for m in sorted(months.keys())]
            values = [months[m] for m in sorted(months.keys())]

        elif option == 'travelCost':
            # 人均花费分析
            cost_ranges = {
                '0-1000元': 0,
                '1001-3000元': 0,
                '3001-5000元': 0,
                '5001-10000元': 0,
                '10000元以上': 0
            }
            for item in original_data:
                if item['fee'] and '人均' in item['fee']:
                    try:
                        fee = int(item['fee'].replace('人均', '').replace('元', '').strip())
                        if fee <= 1000:
                            cost_ranges['0-1000元'] += 1
                        elif 1001 <= fee <= 3000:
                            cost_ranges['1001-3000元'] += 1
                        elif 3001 <= fee <= 5000:
                            cost_ranges['3001-5000元'] += 1
                        elif 5001 <= fee <= 10000:
                            cost_ranges['5001-10000元'] += 1
                        else:
                            cost_ranges['10000元以上'] += 1
                    except ValueError:
                        continue
            labels = list(cost_ranges.keys())
            values = list(cost_ranges.values())

        elif option == 'travelDays':
            # 旅游天数分析
            days_count = {
                '1-3天': 0,
                '4-7天': 0,
                '8-14天': 0,
                '15天以上': 0
            }
            for item in original_data:
                if item['days']:
                    try:
                        days = int(item['days'].replace('共', '').replace('天', '').strip())
                        if days <= 3:
                            days_count['1-3天'] += 1
                        elif 4 <= days <= 7:
                            days_count['4-7天'] += 1
                        elif 8 <= days <= 14:
                            days_count['8-14天'] += 1
                        else:
                            days_count['15天以上'] += 1
                    except ValueError:
                        continue
            labels = list(days_count.keys())
            values = list(days_count.values())

        elif option == 'photoAnalysis':
            # 照片数量分析
            photos_count = {
                '0-50张': 0,
                '51-100张': 0,
                '101-200张': 0,
                '201-500张': 0,
                '500张以上': 0
            }
            for item in original_data:
                if item['photo_nums']:
                    try:
                        photos = int(item['photo_nums'].replace('张照片', '').strip())
                        if photos <= 50:
                            photos_count['0-50张'] += 1
                        elif 51 <= photos <= 100:
                            photos_count['51-100张'] += 1
                        elif 101 <= photos <= 200:
                            photos_count['101-200张'] += 1
                        elif 201 <= photos <= 500:
                            photos_count['201-500张'] += 1
                        else:
                            photos_count['500张以上'] += 1
                    except ValueError:
                        continue
            labels = list(photos_count.keys())
            values = list(photos_count.values())

        elif option == 'companionType':
            # 同伴类型分析
            companion_types = {}
            for item in original_data:
                if item['people']:
                    companion = item['people'].strip()
                    if companion:
                        companion_types[companion] = companion_types.get(companion, 0) + 1
            # 按数量排序
            sorted_companions = sorted(companion_types.items(), key=lambda x: x[1], reverse=True)
            labels = [x[0] for x in sorted_companions]
            values = [x[1] for x in sorted_companions]

        else:
            return jsonify({"error": "无效的选项"}), 400

        return jsonify({
            "labels": labels,
            "values": values,
            "option": option  # 返回选项类型供前端判断
        })
    except FileNotFoundError:
        return jsonify({"error": "未找到 whereToTravel.csv 文件，请先爬取数据"}), 404
    except Exception as e:
        return jsonify({"error": f"服务器错误: {str(e)}"}), 500

@app.route('/data')
def crawl_travel_data():
    data = []
    for page in range(1, 10):
        url = f'https://travel.qunar.com/travelbook/list.htm?page={page}&order=hot_heat'
        response = requests.get(url=url)
        response.encoding = 'utf-8'
        html_data = response.text
        select = parsel.Selector(html_data)
        lis = select.xpath('//ul[@class="b_strategy_list "]/li')
        for li in lis:
            title = li.xpath('./h2/a/text()').get("")
            date = li.xpath('./p[@class="user_info"]//span[@class="date"]/text()').get("")
            days = li.xpath('./p[@class="user_info"]//span[@class="days"]/text()').get("")
            photo_nums = li.xpath('./p[@class="user_info"]//span[@class="photo_nums"]/text()').get("")
            fee = li.xpath('./p[@class="user_info"]//span[@class="fee"]/text()').get("")
            people = li.xpath('./p[@class="user_info"]//span[@class="people"]/text()').get("")
            trip = li.xpath('./p[@class="user_info"]//span[@class="trip"]/text()').get("")
            view = li.xpath('./p[@class="user_info"]//span[@class="icon_view"]/span/text()').get("")
            love = li.xpath('./p[@class="user_info"]//span[@class="icon_love"]/span/text()').get("")
            comment = li.xpath('./p[@class="user_info"]//span[@class="icon_comment"]/span/text()').get("")
            href = li.xpath('./h2/a/@href').get("")

            row = {
                'title': title,
                'date': date,
                'days': days,
                'photo_nums': photo_nums,
                'fee': fee,
                'people': people,
                'trip': trip,
                'view': view,
                'love': love,
                'comment': comment,
                'href': href
            }
            data.append(row)

    # 保存数据到 CSV
    with open('whereToTravel.csv', mode='w', encoding='utf-8', newline='') as f:
        csv_writer = csv.DictWriter(f, fieldnames=list(data[0].keys()))
        csv_writer.writeheader()
        for row in data:
            csv_writer.writerow(row)

    return data


if __name__ == '__main__':
    app.run(debug=True)